#include <sys_config.h>
#include <types.h>
#include <basic_types.h>
#include <mediatypes.h>
#include <api/libc/printf.h>
#include <api/libc/string.h>
#include <osal/osal.h>
#ifndef NEW_DEMO_FRAME
#include <api/libpub29/lib_pub27.h>
#include <api/libpub29/lib_as.h>
#endif

#include <api/libosd/osd_lib.h>

#include "osdobjs_def.h"
#include "string.id"
#include "images.id"
#include "osd_config.h"
#include "control.h"
#include "menus_root.h"
#include "win_com.h"
#include "win_com_popup.h"
#include "win_com_list.h"
#include "win_signalstatus.h"

#include "mobile_input.h"
#include "win_rename.h"

#define DEB_PRINT	soc_printf

#define MAX_INPUT_STR_LEN   MAX_SERVICE_NAME_LENGTH

/*******************************************************************************
*	Objects definition
*******************************************************************************/
extern CONTAINER g_win_find;
UINT16 input_name_str[MAX_INPUT_STR_LEN];
#ifndef KEYBOARD_SUPPORT
extern CONTAINER find_item1;	/* Name */

extern TEXT_FIELD find_title;
extern TEXT_FIELD find_txt1;
extern EDIT_FIELD find_edt1;	/* Name */

static VACTION find_item_edt_keymap(POBJECT_HEAD pObj, UINT32 key);
static PRESULT find_item_edt_callback(POBJECT_HEAD pObj, VEVENT event, UINT32 param1, UINT32 param2);

static VACTION find_item_keymap(POBJECT_HEAD pObj, UINT32 key);
static PRESULT find_item_callback(POBJECT_HEAD pObj, VEVENT event, UINT32 param1, UINT32 param2);

static VACTION find_keymap(POBJECT_HEAD pObj, UINT32 key);
static PRESULT find_callback(POBJECT_HEAD pObj, VEVENT event, UINT32 param1, UINT32 param2);


#define WIN_SH_IDX	  WSTL_POP_WIN_01_HD//WSTL_POP_WIN_01_8BIT//
#define WIN_HL_IDX	  WSTL_POP_WIN_01_HD
#define WIN_SL_IDX	  WSTL_POP_WIN_01_HD
#define WIN_GRY_IDX   WSTL_POP_WIN_01_HD

#define CON_SH_IDX   WSTL_TEXT_04_HD
#define CON_HL_IDX   WSTL_BUTTON_05_HD
#define CON_SL_IDX   WSTL_BUTTON_01_HD
#define CON_GRY_IDX  WSTL_BUTTON_07_HD

#define TXT_SH_IDX   WSTL_TEXT_04_HD
#define TXT_HL_IDX   WSTL_BUTTON_02_FG_HD
#define TXT_SL_IDX   WSTL_BUTTON_01_FG_HD
#define TXT_GRY_IDX  WSTL_BUTTON_07_HD

#define EDT_SH_IDX   WSTL_TEXT_04_HD
#define EDT_HL_IDX   WSTL_BUTTON_04_HD
#define EDT_NAME_HL_IDX   WSTL_BUTTON_09
#define EDT_SL_IDX   WSTL_BUTTON_01_FG_HD
#define EDT_GRY_IDX  WSTL_BUTTON_07_HD

#define SEL_SH_IDX   WSTL_TEXT_04_HD
#define SEL_HL_IDX   WSTL_BUTTON_04_HD
#define SEL_SL_IDX   WSTL_BUTTON_01_FG_HD
#define SEL_GRY_IDX  WSTL_BUTTON_07_HD

#define POPUPSH_IDX	WSTL_BUTTON_POP_SH_HD
#define POPUPHL_IDX	WSTL_BUTTON_POP_HL_HD

#define	W_L     310
#define	W_T     100
#define	W_W     290
#define	W_H     220


#define TITLE_L (W_L + 10)
#define TITLE_T	 (W_T + 10)
#define TITLE_W (W_W - 20)
#define TITLE_H 30

#define CON_L	(W_L + 4)
#define CON_T	(TITLE_T +  TITLE_H + 20)
#define CON_W	(W_W - 8)
#define CON_H	28
#define CON_GAP	0

#define TXT_L_OF  	10
#define TXT_W  		90
#define TXT_H		28
#define TXT_T_OF	((CON_H - TXT_H)/2)

#define SEL_L_OF  (TXT_L_OF + TXT_W)
#define SEL_W  		170
#define SEL_H		28
#define SEL_T_OF	((CON_H - SEL_H)/2)

#define BTN_L_OF	((W_W - BTN_W*2 - BTN_GAP)/2)
#define BTN_T_OF	100
#define BTN_W		80
#define BTN_H		30
#define BTN_GAP    40

#define COLBTN_L	(W_L + 28)
#define COLBTN_T	(W_T + W_H - 100)
#define COLBTN_GAP	4

#define CAPSFLG_L	(W_L + W_W - 100)
#define CAPSFLG_T	(TITLE_T + 20)


#define LDEF_CON(root, varCon,nxtObj,ID,IDl,IDr,IDu,IDd,l,t,w,h,hl,conobj,focusID)		\
    DEF_CONTAINER(varCon,root,nxtObj,C_ATTR_ACTIVE,0, \
    ID,IDl,IDr,IDu,IDd, l,t,w,h, CON_SH_IDX,hl,CON_SL_IDX,CON_GRY_IDX,   \
    find_item_keymap,find_item_callback,  \
    conobj, ID,1)
    
#define LDEF_TXT(root,varTxt,nxtObj,l,t,w,h,resID)		\
    DEF_TEXTFIELD(varTxt,root,nxtObj,C_ATTR_ACTIVE,0, \
    0,0,0,0,0, l,t,w,h, TXT_SH_IDX,TXT_HL_IDX,TXT_SL_IDX,TXT_GRY_IDX,   \
    NULL,NULL,  \
    C_ALIGN_LEFT | C_ALIGN_VCENTER, 0,0,resID,NULL)

#define LDEF_TITLE(root,varTxt,nxtObj,l,t,w,h,resID)		\
    DEF_TEXTFIELD(varTxt,&root,nxtObj,C_ATTR_ACTIVE,0, \
    0,0,0,0,0, l,t,w,h, TXT_SH_IDX,TXT_HL_IDX,TXT_SL_IDX,TXT_GRY_IDX,   \
    NULL,NULL,  \
    C_ALIGN_CENTER | C_ALIGN_VCENTER, 0,0,resID,NULL)


#define LDEF_EDIT(root, varNum, nxtObj, ID, l, t, w, h, hl,align,style,cursormode,pat,sub,str)	\
    DEF_EDITFIELD(varNum,root,nxtObj,C_ATTR_ACTIVE,0, \
    ID,ID,ID,ID,ID, l,t,w,h, EDT_SH_IDX,hl,EDT_SL_IDX,EDT_GRY_IDX,   \
    find_item_edt_keymap,find_item_edt_callback,  \
    align, 4,0,style,pat,17,cursormode,NULL,sub,str)

#define LDEF_MENU_ITEM_EDT(root,varCon,nxtObj,varTxt,varNum,ID,IDu,IDd,\
						l,t,w,h,edthl,resID,align,style,curMode,pat,sub,str) \
    LDEF_CON(&root,varCon,nxtObj,ID,ID,ID,IDu,IDd,l,t,w,h,CON_HL_IDX,&varTxt,ID)   \
    LDEF_TXT(&varCon,varTxt,&varNum,l + TXT_L_OF,t + TXT_T_OF,TXT_W,TXT_H,resID)    \
    LDEF_EDIT(&varCon,varNum,NULL   ,ID, l + SEL_L_OF ,t + SEL_T_OF,SEL_W,SEL_H,edthl,align,style,curMode,pat,sub,str)


#define LDEF_WIN(varCon,nxtObj,l,t,w,h,focusID)		\
    DEF_CONTAINER(varCon,NULL,NULL,C_ATTR_ACTIVE,0, \
    0,0,0,0,0, l,t,w,h, WIN_SH_IDX,WIN_HL_IDX,WIN_SL_IDX,WIN_GRY_IDX,   \
    find_keymap,find_callback,  \
    nxtObj, focusID,0)

LDEF_TITLE(g_win_find, find_title, &find_item1, \
		TITLE_L, TITLE_T, TITLE_W, TITLE_H, RS_HELP_FIND)

extern char name_pat[];
//extern UINT16 input_name_str[];

LDEF_MENU_ITEM_EDT(g_win_find,find_item1,NULL,find_txt1,find_edt1, 1, 1, 1, \
		CON_L, CON_T + (CON_H + CON_GAP)*0, CON_W, CON_H, EDT_NAME_HL_IDX,RS_INFO_NAME,  C_ALIGN_LEFT | C_ALIGN_VCENTER, NORMAL_EDIT_MODE, CURSOR_NORMAL, name_pat,NULL, input_name_str)

LDEF_WIN(g_win_find, &find_title,W_L, W_T,W_W,W_H,1)
#else

extern TEXT_FIELD find_title;
extern TEXT_FIELD find_input;
extern TEXT_FIELD find_txt_char;
TEXT_FIELD find_txt_chars[50];
//SD
#define WIN_SH_IDX           WSTL_POP_WIN_01_8BIT //WSTL_POP_WIN_01

#define TITLE_TXT_SH_IDX    WSTL_POP_TEXT_8BIT //WSTL_TEXT_04_8BIT //WSTL_TEXT_04
#define INPUT_TXT_SH_IDX    WSTL_KEYBOARD_01_8BIT //WSTL_MIXBACK_IDX_02_8BIT //WSTL_KEYBOARD_01//WSTL_BUTTON_09

#define KEY_1_TXT_SH_IDX    WSTL_KEYBOARDBUTTON_01_SH_8BIT//WSTL_KEYBOARDBUTTON_01_SH
#define KEY_1_TXT_HL_IDX    WSTL_KEYBOARDBUTTON_01_HL_8BIT//WSTL_KEYBOARDBUTTON_01_HL

#define KEY_2_TXT_SH_IDX    WSTL_KEYBOARDBUTTON_02_SH_8BIT//WSTL_KEYBOARDBUTTON_02_SH
#define KEY_2_TXT_HL_IDX    WSTL_KEYBOARDBUTTON_02_HL_8BIT//WSTL_KEYBOARDBUTTON_02_HL

#ifndef SD_UI
#define	W_L     500//636//368
#define	W_T     42//82//108//60
#define	W_W     390//240
#define	W_H     541//360


#define TITLE_L  (W_L + 40)
#define TITLE_T	 (W_T + 10)
#define TITLE_W  (W_W - 80)
#define TITLE_H 40

#define INPUT_TXT_L        (W_L + 40)
#define INPUT_TXT_T        (W_T + TITLE_H + 10)
#define INPUT_TXT_W  		(W_W - 80)
#define INPUT_TXT_H		48

#define KEY_L0      46
#define KEY_T0      (10 + TITLE_H + INPUT_TXT_H + 10)
#define KEY_L_GAP   6
#define KEY_T_GAP   4
#define KEY1_W      44 //30
#define KEY2_W      94 //64
#define KEY_H       44 //30

#define COLBTN_L	(W_L + 40)
#define COLBTN_T	(W_T + W_H - 64)
#define COLBTN_GAP	120
#else
#define	W_L     320//636//368
#define	W_T     60//82//108//60
#define	W_W     270//240
#define	W_H     370//360


#define TITLE_L  (W_L + 10)
#define TITLE_T	 (W_T + 10)
#define TITLE_W  (W_W - 30)
#define TITLE_H 32

#define INPUT_TXT_L        (W_L + 40)
#define INPUT_TXT_T        (W_T + TITLE_H + 10)
#define INPUT_TXT_W  		(W_W - 80)
#define INPUT_TXT_H		40

#define KEY_L0      24
#define KEY_T0      (10 + TITLE_H + INPUT_TXT_H + 10)
#define KEY_L_GAP   6
#define KEY_T_GAP   4
#define KEY1_W      30 //30
#define KEY2_W      64 //64
#define KEY_H       30 //30

#define COLBTN_L	(W_L + 20)
#define COLBTN_T	(W_T + W_H - 45)
#define COLBTN_GAP	90

#endif

static VACTION find_btn_keymap(POBJECT_HEAD pObj, UINT32 key);
static PRESULT find_btn_callback(POBJECT_HEAD pObj, VEVENT event, UINT32 param1, UINT32 param2);


static VACTION find_keymap(POBJECT_HEAD pObj, UINT32 key);
static PRESULT find_callback(POBJECT_HEAD pObj, VEVENT event, UINT32 param1, UINT32 param2);

static void set_color_style(void);

#define LDEF_TITLE(root,varTxt,nxtObj,l,t,w,h,resID)		\
    DEF_TEXTFIELD(varTxt,&root,nxtObj,C_ATTR_ACTIVE,0, \
    0,0,0,0,0, l,t,w,h, TITLE_TXT_SH_IDX,TITLE_TXT_SH_IDX,TITLE_TXT_SH_IDX,TITLE_TXT_SH_IDX,   \
    NULL,NULL,  \
    C_ALIGN_CENTER | C_ALIGN_VCENTER, 0,0,resID,NULL)

#define LDEF_INPUTXT(root,varTxt,nxtObj,l,t,w,h,str)\
    DEF_TEXTFIELD(varTxt,&root,nxtObj,C_ATTR_ACTIVE,0, \
    0,0,0,0,0, l,t,w,h, INPUT_TXT_SH_IDX,INPUT_TXT_SH_IDX,INPUT_TXT_SH_IDX,INPUT_TXT_SH_IDX,   \
    NULL,NULL,  \
    C_ALIGN_LEFT | C_ALIGN_VCENTER, 10,0,0,str)

#define LDEF_KEY(root,varTxt,nxtObj,l,t,w,h)\
    DEF_TEXTFIELD(varTxt,&root,nxtObj,C_ATTR_ACTIVE,0, \
    1,1,1,1,1, l,t,w,h, KEY_1_TXT_SH_IDX,KEY_1_TXT_HL_IDX,KEY_1_TXT_SH_IDX,KEY_1_TXT_SH_IDX,   \
    find_btn_keymap,find_btn_callback,  \
    C_ALIGN_CENTER | C_ALIGN_VCENTER, 0,0,0,NULL)

#define LDEF_WIN(varCon,nxtObj,l,t,w,h,focusID)		\
    DEF_CONTAINER(varCon,NULL,NULL,C_ATTR_ACTIVE,0, \
    0,0,0,0,0, l,t,w,h, WIN_SH_IDX,WIN_SH_IDX,WIN_SH_IDX,WIN_SH_IDX,   \
    find_keymap,find_callback,  \
    nxtObj, focusID,0)

//extern UINT16 input_name_str[MAX_INPUT_STR_LEN];
LDEF_TITLE(g_win_find, find_title, &find_input, \
		TITLE_L, TITLE_T, TITLE_W, TITLE_H, RS_HELP_FIND)
LDEF_INPUTXT(g_win_find,find_input,&find_txt_chars[0],\
        INPUT_TXT_L,INPUT_TXT_T,INPUT_TXT_W,INPUT_TXT_H,input_name_str)
LDEF_KEY(g_win_find,find_txt_char,NULL,\
        W_L + KEY_L0,W_T + KEY_T0,KEY1_W,KEY_H)

LDEF_WIN(g_win_find, &find_title,W_L, W_T,W_W,W_H,1)
#endif

/*******************************************************************************
*	Local vriable & function declare
*******************************************************************************/
static void input_callback(UINT8* string);
void win_keyboard_set_title(UINT16 wStringID);

extern CONTAINER g_win_com_lst;
extern OBJLIST	  g_ol_com_list;
UINT16 win_find_prog_num,select_channel_idx;

/*Flag for using for Find windows or edit keyboard*/
static BOOL edit_keyboard_flag = FALSE;
static BOOL check_ok = FALSE;
check_name_func name_valid_func;

static void win_findprog_set_display();
static void set_keyboard_flag(BOOL bPop_keyboard);
#ifdef KEYBOARD_SUPPORT
UINT8 key_chars[] = 
{
    'A', 'B', 'C', 'D', 'E', 'F',
    'G', 'H', 'I', 'J', 'K', 'L',
    'M', 'N', 'O', 'P', 'Q', 'R',
    'S', 'T', 'U', 'V', 'W', 'X',
    'Y', 'Z', '0', '1', '2', '3',
    '4', '5', '6', '7', '8', '9', 
//    '(', ')', '@', '&', '-', '+',
    ' ', '?',0x7F,0xFF
};
#define CHRACTER_CNT 26
#define KEY_CNT     sizeof(key_chars)
#define KEY_COLS    6
#define KEY_ROWS    ((KEY_CNT + KEY_COLS - 1)/KEY_COLS)

void find_init_keys(void);
void find_set_key_display(void);

#endif
/*  mode : 0 -hide, 1 -draw*/
extern void draw_caps_flag(UINT16 x, UINT16 y, UINT32 mode); 
extern void draw_caps_del_colbtn(UINT16 x, UINT16 y, UINT32 mode);
extern void draw_ok_cancel_colbtn(UINT16 x, UINT16 y, UINT32 mode);
extern void draw_caps_colbtn	(UINT16 x, UINT16 y, UINT32 mode);
extern void draw_del_colbtn	(UINT16 x, UINT16 y, UINT32 mode);
extern void draw_ok_colbtn		(UINT16 x, UINT16 y, UINT32 mode);
extern void draw_cancel_colbtn(UINT16 x, UINT16 y, UINT32 mode);
/*******************************************************************************
*	key mapping and event callback definition
*******************************************************************************/
#ifndef KEYBOARD_SUPPORT
static VACTION find_item_edt_keymap(POBJECT_HEAD pObj, UINT32 key)
{
	VACTION act;
	UINT8 bID;
	UINT8 bStyle;
	EDIT_FIELD	*edf;

	edf = (EDIT_FIELD*)pObj;

	bID = OSD_GetObjID(pObj);	

	bStyle = edf->bStyle;
	
	switch(key)
	{
	case V_KEY_0:	case V_KEY_1:	case V_KEY_2:	case V_KEY_3:
	case V_KEY_4:	case V_KEY_5:	case V_KEY_6:	case V_KEY_7:
	case V_KEY_8:	case V_KEY_9:
		act = key - V_KEY_0 + VACT_NUM_0;
		break;
	case V_KEY_LEFT:
		act = VACT_EDIT_LEFT;
		break;
	case V_KEY_RIGHT:
		act= VACT_EDIT_RIGHT;
		break;
	case V_KEY_RED:
		act = VACT_CAPS;
		break;
	case V_KEY_GREEN:
		act = VACT_DEL;
		break;
	default:
		act = VACT_PASS;
	}

	return act;	 
}

static PRESULT find_item_edt_callback(POBJECT_HEAD pObj, VEVENT event, UINT32 param1, UINT32 param2)
{
	PRESULT ret = PROC_PASS;
	UINT8 bID;
	UINT8 unact;
	UINT8 caps;

	bID = OSD_GetObjID(pObj);

	caps = mobile_input_get_caps();

	switch(event)
	{
	case EVN_KEY_GOT:
		ret = mobile_input_proc((EDIT_FIELD*)pObj,(VACTION)(param1>>16), param1 & 0xFFFF, param2);
		if(ret == PROC_LOOP)
			draw_caps_flag(CAPSFLG_L,CAPSFLG_T, 1);
		break;
	case EVN_PRE_CHANGE:
		break;
	case EVN_POST_CHANGE:
		break;
	case EVN_FOCUS_PRE_GET:
	case EVN_PARENT_FOCUS_PRE_GET:
	case EVN_FOCUS_PRE_LOSE:
	case EVN_PARENT_FOCUS_PRE_LOSE:		
		break;
	default:
		break;
	}

	return ret;
}

static VACTION find_item_keymap(POBJECT_HEAD pObj, UINT32 key)
{
	VACTION act = VACT_PASS;

	return act;	
}

static PRESULT find_item_callback(POBJECT_HEAD pObj, VEVENT event, UINT32 param1, UINT32 param2)
{
	PRESULT ret = PROC_PASS;
	return ret;
}

#define VACT_OK		(VACT_PASS + 1)
#define VACT_CANCEL	(VACT_PASS + 2)

static VACTION find_keymap(POBJECT_HEAD pObj, UINT32 key)
{
	VACTION act;
	switch(key)
	{
	case V_KEY_EXIT:
	case V_KEY_MENU:
	case V_KEY_FIND:
	case V_KEY_YELLOW:
		act = VACT_OK;
		break;
	case V_KEY_BLUE:
		act = VACT_CANCEL;
		break;		
	default:
		act = VACT_PASS;
	}

	return act;	
}

static PRESULT find_callback(POBJECT_HEAD pObj, VEVENT event, UINT32 param1, UINT32 param2)
{
	PRESULT ret = PROC_PASS;
	VACTION unact;
	mobile_input_type_t mobile_input_type;

	mobile_input_type.type 		= MOBILE_INPUT_NORMAL;
	mobile_input_type.caps_flag = MOBILE_CAPS_INIT_LOW;
	mobile_input_type.maxlen    = MAX_INPUT_STR_LEN;
	mobile_input_type.fixlen_flag = 0;
	mobile_input_type.callback	= input_callback;

	switch(event)
	{
	case EVN_PRE_OPEN:
        #if defined(SUPPORT_CAS9) || defined(SUPPORT_CAS7)
			if(get_mmi_showed()==1||get_mmi_showed()==6)
			{
				//win_mmipopup_close(1);
					#if defined(SUPPORT_CAS7)//SUPPORT_CAS7 alone
    						win_mmipopup_close(1);
    					#else
						win_pop_msg_close(1);
					#endif
				//win_fingerpop_close();
			}
			if((0==get_mmi_showed()) && (GetSignalStatausShow()))
				ShowSignalStatusOSDOnOff(0);
        #endif	
		if(!edit_keyboard_flag)
			win_keyboard_set_title(RS_HELP_FIND);
		win_find_prog_num = 0;
 		mobile_input_init(&find_edt1,&mobile_input_type);

		//patch for clear find editfield content
		if(menu_stack_get(-1) == NULL)
			OSD_SetEditFieldContent(&find_edt1,STRING_UNICODE,(UINT32)"");
		break;
	case EVN_POST_OPEN:
		draw_caps_flag(CAPSFLG_L,CAPSFLG_T, 1);
		//draw_caps_del_colbtn(COLBTN_L, COLBTN_T,1);
	 	//draw_ok_cancel_colbtn(COLBTN_L, COLBTN_T + 40,1);	 	
	 	draw_caps_colbtn(COLBTN_L, 		COLBTN_T, 1);
		draw_del_colbtn(COLBTN_L + 100, 	COLBTN_T, 1);
		draw_ok_colbtn(COLBTN_L, 			COLBTN_T + 40, 1);
		draw_cancel_colbtn(COLBTN_L+ 100, 	COLBTN_T + 40, 1);
		break;
	case EVN_PRE_CLOSE:
		/* Make OSD not flickering */
		//*((UINT32*)param2) &= ~C_CLOSE_CLRBACK_FLG;			
		break;
	case EVN_POST_CLOSE:
        #if defined(SUPPORT_CAS9) || defined(SUPPORT_CAS7)
            restore_ca_msg_when_exit_win();
        #endif
		break;			
	case EVN_UNKNOWN_ACTION:
		unact = (VACTION)(param1>>16);
		if(unact == VACT_OK)
		{
			if(!edit_keyboard_flag)
			{
				if(win_find_prog_num == 0)
					ret = PROC_LEAVE;				
				else
				{
					//OSD_ObjClose(((POBJECT_HEAD)&g_win_find,C_UPDATE_ALL);
					OSD_ClearObject((POBJECT_HEAD)&g_win_find, C_UPDATE_ALL);
					menu_stack_pop();
					menu_stack_push((POBJECT_HEAD)&g_win_com_lst);
					ret = PROC_LOOP;
				}
			}
			else
			{
				check_ok = TRUE;
				ret = PROC_LEAVE;
				if(name_valid_func != NULL)
				{
					if(name_valid_func(input_name_str) == 0)
					{
						ret = PROC_LEAVE;				
					}
					else
					{
						ret = PROC_LOOP;
					}
				}
			}
		}
		else if(unact == VACT_CANCEL)
		{
			if(!edit_keyboard_flag)
			{
				if(win_find_prog_num > 0)
					OSD_ClearObject((POBJECT_HEAD)&g_win_com_lst, C_UPDATE_ALL);

				ret = PROC_LEAVE;
			}
			else
			{
				ret = PROC_LEAVE;
			}
		}		
	}
	return ret;
}

#else

//#define VACT_DEL    (VACT_PASS + 1)
#define VACT_OK     (VACT_PASS + 2)
#define VACT_CANCEL (VACT_PASS + 3)

static VACTION find_btn_keymap(POBJECT_HEAD pObj, UINT32 key)
{
	VACTION act;
	switch(key)
	{
	case V_KEY_ENTER:
	    act = VACT_ENTER;
	    break;
	case V_KEY_RED:
	    act = VACT_DEL;
	    break;
	case V_KEY_BLUE:
	    act = VACT_OK;
	    break;
	case V_KEY_YELLOW:
	    act = VACT_CAPS;
	    break;
	default:
	    act = VACT_PASS;
	}
	return act;
}

static PRESULT find_btn_callback(POBJECT_HEAD pObj, VEVENT event, UINT32 param1, UINT32 param2)
{
	PRESULT ret = PROC_PASS;
	VACTION unact;    
	UINT8 i,bID;
	UINT32 str_len;
	char ch,str_temp[2];

	bID = OSD_GetObjID(pObj);
	switch(event)
	{
		case EVN_UNKNOWN_ACTION:
		unact = (VACTION)(param1>>16);
		ret = PROC_LOOP;
		str_len = ComUniStrLen(input_name_str);
	    
		if(unact == VACT_DEL || (unact == VACT_ENTER && key_chars[bID - 1] == 0x7F) )   /* DEL */
		{
			if(str_len>0)
			{
				input_name_str[str_len-1] = 0;
				OSD_DrawObject((POBJECT_HEAD)&find_input, C_UPDATE_ALL);
				if(!edit_keyboard_flag)
				{
					input_callback((UINT8*)input_name_str);                
				}
			}
		}
		else if(unact == VACT_OK || (unact == VACT_ENTER && key_chars[bID - 1] == 0xFF) ) /* OK */
		{
			check_ok = TRUE;
			ret = PROC_LEAVE;
			if(name_valid_func != NULL)
			{
				if(name_valid_func(input_name_str) == 0)
				{
					ret = PROC_LEAVE;				
				}
				else
				{
					ret = PROC_LOOP;
				}
			}
		}
		else if(unact == VACT_ENTER)
		{
			ch = key_chars[bID - 1];
			if(str_len < MAX_INPUT_STR_LEN)
			{
				SetUniStrCharAt(input_name_str,ch,str_len);
				input_name_str[str_len + 1] = 0;
				OSD_DrawObject((POBJECT_HEAD)&find_input, C_UPDATE_ALL);
				if(!edit_keyboard_flag)
				{
				        input_callback((UINT8*)input_name_str);
				}
			}
		}
		else if(unact == VACT_CAPS)
		{
			str_temp[1] = '\0';
			for(i = 0;i < CHRACTER_CNT;i++)
			{
				if((key_chars[i] >= 'a') && (key_chars[i] <= 'z'))
				{
					key_chars[i] = key_chars[i] - ('a' - 'A');
				}
				else if((key_chars[i] >= 'A') && (key_chars[i] <= 'Z'))
				{
					key_chars[i] = key_chars[i] + ('a' - 'A');
				}
				str_temp[0] = key_chars[i];
				OSD_SetTextFieldContent(&find_txt_chars[i], STRING_ANSI,(UINT32)str_temp);
			}
			OSD_TrackObject((POBJECT_HEAD)&g_win_find, C_DRAW_SIGN_EVN_FLG | C_UPDATE_ALL);
			//draw_caps_colbtn_ext(COLBTN_L,  COLBTN_T, 1,IM_EPG_COLORBUTTON_YELLOW);
			//draw_del_colbtn_ext(COLBTN_L + 120, COLBTN_T, 1,IM_EPG_COLORBUTTON_RED);
			//draw_ok_colbtn_ext(COLBTN_L + 240,COLBTN_T, 1,IM_EPG_COLORBUTTON_BLUE);

    		draw_caps_colbtn_ext(COLBTN_L,  COLBTN_T, 1,IM_EPG_COLORBUTTON_YELLOW);
    		draw_del_colbtn_ext(COLBTN_L + COLBTN_GAP,           COLBTN_T, 1,IM_EPG_COLORBUTTON_RED);
    		draw_ok_colbtn_ext(COLBTN_L + 2*COLBTN_GAP,       COLBTN_T, 1,IM_EPG_COLORBUTTON_BLUE);
        }
		break;
	}
	return ret;
}

static VACTION find_keymap(POBJECT_HEAD pObj, UINT32 key)
{
    VACTION act;
    switch(key)
    {

	case V_KEY_0:	case V_KEY_1:	case V_KEY_2:	case V_KEY_3:
	case V_KEY_4:	case V_KEY_5:	case V_KEY_6:	case V_KEY_7:
	case V_KEY_8:	case V_KEY_9:
		act = key - V_KEY_0 + VACT_NUM_0;
        break;
	case V_KEY_LEFT:
	    act = VACT_CURSOR_LEFT;
	    break;
	case V_KEY_RIGHT:
	    act = VACT_CURSOR_RIGHT;
	    break;
	case V_KEY_UP:
	    act = VACT_CURSOR_UP;
	    break;
	case V_KEY_DOWN:
	    act = VACT_CURSOR_DOWN;
	    break;
	case V_KEY_EXIT:
	case V_KEY_MENU:
		check_ok = FALSE;
		act = VACT_CLOSE;
	    break;
/*		
	case V_KEY_GREEN:
	   act = VACT_CANCEL;
	    break;*/
	default:
	    act = VACT_PASS;        
	}
	return act;
}

static PRESULT find_callback(POBJECT_HEAD pObj, VEVENT event, UINT32 param1, UINT32 param2)
{
	PRESULT ret = PROC_PASS;
	VACTION unact;
	UINT8 bID;
	UINT32 pos0;
    
	switch(event)
	{
	case EVN_PRE_OPEN:

        #if defined(SUPPORT_CAS9) || defined(SUPPORT_CAS7)
			if(get_mmi_showed()==1||get_mmi_showed()==6)
			{
				//win_mmipopup_close(1);
					#if defined(SUPPORT_CAS7)//SUPPORT_CAS7 alone
    						win_mmipopup_close(1);
    					#else
						win_pop_msg_close(1);
					#endif
				//win_fingerpop_close();
			}
			if((0==get_mmi_showed()) && (GetSignalStatausShow()))
				ShowSignalStatusOSDOnOff(0);
        #endif	
		#ifdef SUPPORT_CAS_A
			/* clear msg first */
			api_abel_osd_close_cas_msg();
			on_event_cc_pre_callback();
		#endif
		
        set_color_style();
        api_inc_wnd_count();
		if(!edit_keyboard_flag)//when flag is TRUE,it is for edit use
		{
			name_valid_func = NULL;
			MEMSET(input_name_str,0,sizeof(input_name_str));
			win_find_prog_num = 0;
            win_keyboard_set_title(RS_HELP_FIND);
		}
		
		find_init_keys();
		find_set_key_display();
		break;
	case EVN_POST_OPEN:	
		draw_caps_colbtn_ext(COLBTN_L,  COLBTN_T, 1,IM_EPG_COLORBUTTON_YELLOW);
		draw_del_colbtn_ext(COLBTN_L + COLBTN_GAP,           COLBTN_T, 1,IM_EPG_COLORBUTTON_RED);
		draw_ok_colbtn_ext(COLBTN_L + 2*COLBTN_GAP,       COLBTN_T, 1,IM_EPG_COLORBUTTON_BLUE);
        break;
	case EVN_PRE_CLOSE:
		/* Make OSD not flickering */

		#ifdef SUPPORT_CAS7
		win_mmipopup_close(1);				
		#endif
        if(edit_keyboard_flag)
        {
		    *((UINT32*)param2) &= ~C_CLOSE_CLRBACK_FLG;
        }
        if(!edit_keyboard_flag)
		{
			if(win_find_prog_num > 0)
			{
				OSD_ClearObject((POBJECT_HEAD)&g_win_find, C_UPDATE_ALL);
				menu_stack_pop();
				menu_stack_push((POBJECT_HEAD)&g_win_com_lst);
				ret = PROC_LOOP;
			}
		}
		break;
	case EVN_POST_CLOSE:
        api_dec_wnd_count();
        #if defined(SUPPORT_CAS9) || defined(SUPPORT_CAS7)
            restore_ca_msg_when_exit_win();
        #endif
		#ifdef SUPPORT_CAS_A
			on_event_cc_post_callback();
		#endif	
		break;			
	case EVN_UNKNOWN_ACTION:     
		unact = (VACTION)(param1>>16);
		if(unact == VACT_CANCEL)
		{
			if((win_find_prog_num > 0) && (!edit_keyboard_flag))
			{
				OSD_ClearObject((POBJECT_HEAD)&g_win_com_lst, C_UPDATE_ALL);
			        win_find_prog_num = 0;
			}
			check_ok = FALSE;
			ret = PROC_LEAVE;
		}
		else if(unact >= VACT_NUM_0 && unact<= VACT_NUM_9)
		{
		    for(pos0=0;pos0<KEY_CNT;pos0++)
		    {
		        if(key_chars[pos0] == '0')
		            break;
		    }
		    bID = pos0+1 + unact - VACT_NUM_0;
		    OSD_ChangeFocus( pObj,bID,C_DRAW_SIGN_EVN_FLG | C_UPDATE_FOCUS);
		    ap_send_msg(CTRL_MSG_SUBTYPE_KEY_UI, V_KEY_ENTER, TRUE);
		    ret = PROC_LOOP;
		}
	}
	return ret;
}

void find_set_key_display(void)
{
    TEXT_FIELD  *txt;
    UINT32 i,row,col;
    char str[10];    
    UINT8 ch;
    
    for(i=0;i<KEY_CNT;i++)
    {
        txt = &find_txt_chars[i];
        row = i/KEY_COLS;
        col = i%KEY_COLS;        
         ch = key_chars[i];
        if(ch == 0xFF)
            STRCPY(str,"OK");
        else if(ch == ' ')
            STRCPY(str,"SP");
	else if(ch == 0x7F)
            STRCPY(str,"<-");
        else
        {
            str[0] = ch;
            str[1] = 0;
        }

        OSD_SetTextFieldContent(txt, STRING_ANSI, (UINT32)str);            
    }

}

#define LEFT_RIGHT_ORDER
void find_init_keys(void)
{
    //static UINT32 flag = 0;
    UINT32 i,row,col;
    UINT16 l0,w0,x,y,w,h;
    TEXT_FIELD  *txt,*txto;
    UINT8 bID,bLeftID,bRightID,bUpID,bDownID;
    UINT8 ch;
    

    //if(flag)
    //    return;

    l0 = w0 = 0;
    txto = &find_txt_char;
	OSD_SetColor(txto,KEY_1_TXT_SH_IDX,KEY_1_TXT_HL_IDX,KEY_1_TXT_SH_IDX,KEY_1_TXT_SH_IDX);

    for(i=0;i<KEY_CNT;i++)
    {
        txt = &find_txt_chars[i];
        MEMCPY(txt,txto,sizeof(TEXT_FIELD));
        row = i/KEY_COLS;
        col = i%KEY_COLS;
        if(col==0)
        {
            l0 = 0;
            w0 = 0;
        }
        if(key_chars[i] == ' ' || key_chars[i] ==0xFF)
        {
            w = KEY2_W;
			OSD_SetColor(txt,KEY_2_TXT_SH_IDX,KEY_2_TXT_HL_IDX,KEY_2_TXT_SH_IDX,KEY_2_TXT_SH_IDX);
        }
        else
            w = KEY1_W;
        h = KEY_H;
        x = W_L + KEY_L0 + l0;
        //if(w0)            x += KEY_L_GAP;
        y = W_T + KEY_T0 + (KEY_H + KEY_T_GAP)*row;
        OSD_SetRect(&txt->head.frame, x, y, w, h);
        bID  = i+1;
#ifdef LEFT_RIGHT_ORDER
        if(i != 0)
            bLeftID = bID-1;
        else
            bLeftID = KEY_CNT;
#else
        if(col == 0)
            bLeftID = (row + 1)*KEY_COLS;
        else
            bLeftID = bID-1;        
#endif  
        if(bLeftID > KEY_CNT)
            bLeftID = KEY_CNT;        

#ifdef LEFT_RIGHT_ORDER
        if( i != (KEY_CNT - 1) )
            bRightID = bID+1;
        else
            bRightID = 1;
#else
        if(col == (KEY_COLS - 1)  || i==(KEY_CNT - 1) )
            bRightID = (row + 1)*KEY_COLS + 1;
        else 
            bRightID = bID+1;
#endif  
        if(bRightID > KEY_CNT)
            bRightID = KEY_CNT;

        if(row == 0)
        {
            if(col == 0 || col == 1)
                bUpID = (KEY_ROWS - 1)*KEY_COLS + 1;
            else if(col==2 || col == 3)
                bUpID = (KEY_ROWS - 1)*KEY_COLS + col;
            else
                bUpID = KEY_CNT;            
        }
        else if( row == (KEY_ROWS - 1) )
        {
            if(col == 0)
                bUpID = (row -1)* KEY_COLS + 1;
            else if(col == 1 || col == 2)
                bUpID = (row - 1) * KEY_COLS + 2 + col;
            else
                bUpID = row * KEY_COLS;            
        }
        else 
            bUpID = (row - 1)* KEY_COLS + 1 + col;
        if(bUpID > KEY_CNT)
            bUpID = KEY_CNT;

        if(row == (KEY_ROWS - 2) )
        {
            if(col == 0 || col == 1)
                bDownID = (KEY_ROWS - 1)*KEY_COLS + 1;
            else if(col == 2 || col == 3)
                bDownID = (KEY_ROWS - 1)*KEY_COLS + col;
            else
                bDownID = (KEY_ROWS - 1)*KEY_COLS + 4;
        }
        else if(row == (KEY_ROWS - 1) )
        {
            if(col == 0)
                bDownID = 1;
            else if(col == 1 || col == 2)
                bDownID = col + 2;
            else
                bDownID = KEY_COLS;
        }
        else
            bDownID = (row + 1)*KEY_COLS + 1 + col;

        if(bDownID > KEY_CNT)
            bDownID = KEY_CNT;

        OSD_SetID(txt, bID, bLeftID, bRightID, bUpID, bDownID);
        //soc_printf("%d,%d,%d,%d,%d\n",bID, bLeftID, bRightID, bUpID, bDownID);

        OSD_SetTextFieldStrPoint(txt, &display_strs[row][5*col]);
        if(i != KEY_CNT - 1)
            OSD_SetObjpNext(txt, &find_txt_chars[i+1]);
        else
            OSD_SetObjpNext(txt,NULL);
        l0 += (w + KEY_L_GAP);
        w0 = w;
    }
	//flag = 1;
}
#endif

///////////////////////////////////////////////////////////////////////////////////////////////////////
// The following are same for Keyboard or mobile style input.
static void input_callback(UINT8* string)
{
	UINT32 prog_num = 0;
	UINT16* unistr;
	P_NODE p_node;
	UINT32 find_cnt;
	
	find_cnt = win_find_prog_num;

	unistr = (UINT16*)string;
	if(ComUniStrLen(unistr) == 0)
 		win_find_prog_num = 0;
	else
		win_find_prog_num = find_prog_by_name(string,&p_node);

	if(win_find_prog_num == 0)
	{	
		if( find_cnt!=0)
			OSD_ClearObject((POBJECT_HEAD)&g_win_com_lst, C_UPDATE_ALL);
	}
	else
	{
		win_findprog_set_display();
		OSD_TrackObject((POBJECT_HEAD)&g_win_com_lst, C_DRAW_SIGN_EVN_FLG | C_UPDATE_ALL);
	}	
}
#ifndef SD_UI
#define W_PROG_L 100//20
#define W_PROG_T 42 //80//80
#define W_PROG_W 390//280
#define W_PROG_H 541//280
#else
#define W_PROG_L 50//20
#define W_PROG_T 60 //80//80
#define W_PROG_W 270//280
#define W_PROG_H 370//280
#endif

static VACTION win_findprog_keymap(POBJECT_HEAD pObj, UINT32 key)
{
	VACTION vact = VACT_PASS;
	switch(key)
	{
		case V_KEY_EXIT:
		case V_KEY_MENU:
			vact = VACT_CLOSE;
			break;
		default:
			break;
	}
	return vact;	
}

static PRESULT win_findprog_con_defcallback(POBJECT_HEAD pObj, VEVENT event, UINT32 param1, UINT32 param2)
{
	switch(event)
	{
	case EVN_PRE_OPEN:
        #if defined(SUPPORT_CAS9) || defined(SUPPORT_CAS7)
			if(get_mmi_showed()==1||get_mmi_showed()==6)
			{
				//win_mmipopup_close(1);
					#if defined(SUPPORT_CAS7)//SUPPORT_CAS7 alone
    						win_mmipopup_close(1);
    					#else
						win_pop_msg_close(1);
					#endif
				//win_fingerpop_close();
			}
			if((0==get_mmi_showed()) && (GetSignalStatausShow()))
				ShowSignalStatusOSDOnOff(0);
        #endif
		break;
	case EVN_PRE_CLOSE:
        #if defined(SUPPORT_CAS9) || defined(SUPPORT_CAS7)
            restore_ca_msg_when_exit_win();
        #endif
		/* Make OSD not flickering */
		//*((UINT32*)param2) &= ~C_CLOSE_CLRBACK_FLG;	
		break;
	default:
		break;
	}
	
	
    return PROC_PASS;
}

static PRESULT win_findprog_callback(POBJECT_HEAD pObj, VEVENT event, UINT32 param1, UINT32 param2)
{
	PRESULT cbRet = PROC_PASS;
	
	UINT32 i,wTop,prog_idx,nStrLen,k;

	UINT16 channel,str_len;
	UINT16 unistr[50];
	char prog_pre[20];
	P_NODE  p_node;
	OBJLIST* ol = (OBJLIST*)pObj;

	UINT16 dep,cnt;
    UINT16 last_prog_pos = 0xffff;
    P_NODE p_node_temp;

	dep = OSD_GetObjListPage(ol);
	cnt = OSD_GetObjListCount(ol);

	if(event==EVN_PRE_DRAW)
	{		
    	wTop = OSD_GetObjListTop(ol);
    	for(i=0;i<dep && (i+wTop)<cnt;i++)
		{
			prog_idx = i + wTop;
			get_find_prog_by_pos(prog_idx,&p_node);

			sprintf(prog_pre,"%04d  %s",prog_idx + 1,(p_node.ca_mode==0)? "" :  "$");
			nStrLen = ComAscStr2Uni(prog_pre, unistr);
			ComUniStrCopy(&unistr[nStrLen], (UINT16*)p_node.service_name);

			win_comlist_set_str(i + wTop, NULL, (char*)unistr,0);
		}
	}
	else if(event==EVN_POST_CHANGE)
	{
		cbRet = PROC_LEAVE;
		select_channel_idx = win_comlist_get_selitem();
		get_find_prog_by_pos(select_channel_idx,&p_node);
		select_channel_idx = get_prog_pos(p_node.prog_id);
		
		clear_node_find_flag();

		//UIChChgPlayProg(0, select_channel_idx);
        #ifdef MULTI_DESCRAMBLE  //fixed bug47021:change to CA program,can't not descramble
            last_prog_pos = sys_data_get_cur_group_cur_mode_channel();
            get_prog_at(last_prog_pos,&p_node_temp);
            libc_printf("%s,prog_pos=%d,prog_id=%d\n",__FUNCTION__,last_prog_pos,p_node_temp.prog_id);
            /*stop pre channel's filter,ts_stream and so on*/
            if(api_mcas_get_prog_record_flag(p_node_temp.prog_id) == FALSE)   //if the program is recording,don't stop descramble service
            {
                libc_printf("%s,stop service\n",__FUNCTION__);
                api_mcas_stop_service_multi_des(p_node_temp.prog_id,0xffff);
            }
        #endif
		api_play_channel(p_node.prog_id, TRUE, TRUE, TRUE);
	}

	return cbRet;
}

static void win_findprog_set_display()
{
	UINT16 count,dep;
	UINT16 style;
	struct OSDRect rW;
	//UINT16 height;
	PFN_KEY_MAP lstkeymap,winkeymap;
	PFN_CALLBACK callback;
	S_NODE s_node;
	UINT16 channel,str_len;
	char str[50];


    //TODO get find program number here.
	count = win_find_prog_num;
	#ifndef SD_UI
	dep = 11;
	#else
	dep = 8;
	#endif
	//height = 28 * dep;
	style = LIST_VER | LIST_ITEMS_NOCOMPLETE | LIST_SCROLL | LIST_SINGLE_SLECT | LIST_FULL_PAGE;

	OSD_SetRect(&rW,W_PROG_L,W_PROG_T, W_PROG_W,W_PROG_H);

	win_comlist_reset();
	win_comlist_set_sizestyle(count, dep,style);    
	win_comlist_ext_enable_scrollbar(TRUE);	
	win_comlist_set_frame(rW.uLeft, rW.uTop, rW.uWidth, rW.uHeight);
	win_comlist_set_align(10,0, C_ALIGN_LEFT | C_ALIGN_VCENTER);
	win_comlist_ext_set_ol_frame(rW.uLeft  + 10,rW.uTop + 46, rW.uWidth - 20, rW.uHeight - 92);
	//win_comlist_ext_set_win_style(WSTL_POPUP_WIN_IDX);
	//win_comlist_ext_set_ol_items_style(MENU_FAV_ITEM_SH_IDX, MENU_FAV_ITEM_HL_IDX, 0);

//	win_comlist_ext_set_title(str);
	winkeymap = win_findprog_keymap;
	callback  = win_findprog_callback;
	//win_comlist_set_mapcallback(NULL,winkeymap,callback);
	win_comlist_set_mapcallback_ex(NULL,winkeymap,callback,win_findprog_con_defcallback);
}

void win_keyboard_set_title(UINT16 wStringID)
{
	PTEXT_FIELD txt = &find_title;
	OSD_SetTextFieldContent(txt,STRING_ID, wStringID);
}

BOOL win_keyboard_rename_open(UINT16* set_name,UINT8** ret_name,check_name_func check_func )
{
	UINT16 strID;
	UINT32 hkey;
	PRESULT ret;
	TEXT_FIELD	*txt;
	EDIT_FIELD *edf;
	CONTAINER	*win;

	win = &g_win_find;
	wincom_backup_region(&win->head.frame);
    set_color_style();
    BOOL old_value = ap_enable_key_task_get_key(TRUE);

	strID = RS_HELP_RENAME;
	win_keyboard_set_title(strID);
	name_valid_func = check_func;
	check_ok = FALSE;
#ifndef KEYBOARD_SUPPORT
	edf = &find_edt1;
	MEMSET(input_name_str,0,sizeof(input_name_str));
	OSD_SetEditFieldContent(edf, STRING_UNICODE, (UINT32)set_name);
#else
	txt = &find_input;
	MEMSET(input_name_str,0,sizeof(input_name_str));
	OSD_SetTextFieldContent(txt, STRING_UNICODE,(UINT32)set_name);
#endif
   
	win = &g_win_find;
	set_keyboard_flag(TRUE);

    find_init_keys();
	find_set_key_display();
    
	ret = OSD_ObjOpen((POBJECT_HEAD)win, 0);	
	while(ret != PROC_LEAVE)
	{
		hkey = ap_get_key_msg();
		if(hkey == INVALID_HK || hkey == INVALID_MSG)
		    continue;

		ret = OSD_ObjProc((POBJECT_HEAD)win, (MSG_TYPE_KEY<<16),hkey, 0);
	}
	if(check_ok)
	{
		*ret_name = (UINT8*)input_name_str;
	}
	else
	{
		*ret_name = NULL;
	}
	set_keyboard_flag(FALSE);
	wincom_restore_region();
    ap_enable_key_task_get_key(old_value);

	return (check_ok);
}
static void set_keyboard_flag(BOOL bPop_keyboard)
{
	edit_keyboard_flag = bPop_keyboard;
}

static void set_color_style(void)
{
    TEXT_FIELD	*txt;
	CONTAINER	*win;

    win = &g_win_find;
    OSD_SetColor((POBJECT_HEAD)win,WIN_SH_IDX,WIN_SH_IDX,WIN_SH_IDX,WIN_SH_IDX);
    txt = &find_title;
    OSD_SetColor((POBJECT_HEAD)txt,TITLE_TXT_SH_IDX,TITLE_TXT_SH_IDX,TITLE_TXT_SH_IDX,TITLE_TXT_SH_IDX);   
    txt = &find_input;
    OSD_SetColor((POBJECT_HEAD)txt,INPUT_TXT_SH_IDX,INPUT_TXT_SH_IDX,INPUT_TXT_SH_IDX,INPUT_TXT_SH_IDX);   
    txt = &find_txt_char;
    OSD_SetColor((POBJECT_HEAD)txt,KEY_1_TXT_SH_IDX,KEY_1_TXT_HL_IDX,KEY_1_TXT_SH_IDX,KEY_1_TXT_SH_IDX);
}
